package Security;

import Files.MSJ_Files;
import Utils.MSJ_JOptionPane;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;

/**
 * <b>Use this class to Encrypt your Strings to more security.</b>
 *
 * @author Mohamed Tarek Salama
 * @version 1.2 BETA
 */
public class MSJ_Encryption {

    public MSJ_Encryption() {
    }

    public void DES_file() {
        new MSJ_Files().writefile("d:/DESKey.key", "fzth7aab");
    }

    public void mono_file() {
        new MSJ_Files().writefile("d:/monoKey.key", "199");
    }

    /**
     * Encrypt with Mono Alphabetic algorithm.
     *
     * @param message : Text string that will be encrypted.
     * @return String: Text that encrypted.
     */
    public String encrypt_mono(String message) {
        int key;
        String skey = new MSJ_Files().readfile("d:/monokey.key");
        if ("".equals(skey)) {
            mono_file();
            skey = new MSJ_Files().readfile("d:/monokey.key");
            MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
        }
        try {
            key = Integer.parseInt(skey);
        } catch (NumberFormatException ex) {
            mono_file();
            skey = new MSJ_Files().readfile("d:/monokey.key");
            key = Integer.parseInt(skey);
            MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
        }
        String output = "";
        for (int i = 0; i < message.length(); i++) {
            output += (char) (((int) message.charAt(i)) + key);
        }
        return output;
    }

    /**
     * Decrypt with Mono Alphabetic algorithm.
     *
     * @param message : Text string that will be decrypted.
     * @return String : Text that decrypted.
     */
    public String decrypt_mono(String message) {
        int key;
        String skey = new MSJ_Files().readfile("d:/monokey.key");
        if ("".equals(skey)) {
            mono_file();
            skey = new MSJ_Files().readfile("d:/monokey.key");
            MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
        }
        try {
            key = Integer.parseInt(skey);
        } catch (NumberFormatException ex) {
            MSJ_JOptionPane.show_Error_Message("Number Format Error\n" + ex.toString());
            mono_file();
            skey = new MSJ_Files().readfile("d:/monokey.key");
            key = Integer.parseInt(skey);
            MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
        }
        String output = "";
        for (int i = 0; i < message.length(); i++) {
            output += (char) (((int) message.charAt(i)) - key);
        }
        return output;
    }

    /**
     * Encrypt with DES algorithm.
     *
     * @param message String : Text string that will be encrypted.
     * @return String : Text that encrypted.
     */
    public String encrypt_DES(String message) {
        Cipher ecipher;
        byte[] enc = null;
        String keyfromfile = "";
        try {
            ecipher = Cipher.getInstance("DES");
            keyfromfile = new MSJ_Files().readfile("d:/DESkey.key");
            if ("".equals(keyfromfile)) {
                DES_file();
                keyfromfile = new MSJ_Files().readfile("d:/DESkey.key");
                MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
            }
            //----------------------------------------------
            DESKeySpec deskeyspec = new DESKeySpec(keyfromfile.getBytes());
            SecretKeyFactory secretkey = SecretKeyFactory.getInstance("DES");
            SecretKey desKey = secretkey.generateSecret(deskeyspec);
            //----------------------------------------------
            ecipher.init(Cipher.ENCRYPT_MODE, desKey);
            byte[] utf8 = message.getBytes("UTF8");
            enc = ecipher.doFinal(utf8);
        } catch (InvalidKeySpecException ex) {
            MSJ_JOptionPane.show_Error_Message("Invalid key specification\n" + ex.toString());
        } catch (InvalidKeyException ex) {
            MSJ_JOptionPane.show_Error_Message("Error in generating the secret key\n Or in valid key generated\n"
                    + ex.toString());
        } catch (IllegalBlockSizeException ex) {
            MSJ_JOptionPane.show_Error_Message("Error illegal block size\n" + ex.toString());
        } catch (BadPaddingException ex) {
            MSJ_JOptionPane.show_Error_Message("Error bad Padding\n" + ex.toString());
        } catch (UnsupportedEncodingException ex) {
            MSJ_JOptionPane.show_Error_Message("Error Unsupported encoding\n" + ex.toString());
        } catch (NoSuchAlgorithmException ex) {
            MSJ_JOptionPane.show_Error_Message("Error no such algorithm\n" + ex.toString());
        } catch (NoSuchPaddingException ex) {
            MSJ_JOptionPane.show_Error_Message("Error no such Padding\n" + ex.toString());
        }
        if (!"".equals(keyfromfile)) {
            return new sun.misc.BASE64Encoder().encode(enc);
        } else {
            return "";
        }
    }

    /**
     * Decrypted with DES algorithm.
     *
     * @param message : String : Text string that will be decrypted.
     * @return String : Text that decrypted.
     */
    public String decrypt_DES(String message) {
        Cipher dcipher;
        String output = "";
        String keyfromfile;
        try {
            dcipher = Cipher.getInstance("DES");
            keyfromfile = new MSJ_Files().readfile("d:/DESkey.key");
            if ("".equals(keyfromfile)) {
                DES_file();
                keyfromfile = new MSJ_Files().readfile("d:/DESkey.key");
                MSJ_JOptionPane.show_Info_Message("Error Fixed Correctly");
            }
            //----------------------------------------------
            DESKeySpec keyspec = new DESKeySpec(keyfromfile.getBytes());
            SecretKeyFactory secretkey = SecretKeyFactory.getInstance("DES");
            SecretKey desKey = secretkey.generateSecret(keyspec);
            //----------------------------------------------
            dcipher.init(Cipher.DECRYPT_MODE, desKey);
            byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(message);
            byte[] utf8 = dcipher.doFinal(dec);
            output = new String(utf8, "UTF8");
        } catch (InvalidKeySpecException ex) {
            MSJ_JOptionPane.show_Error_Message("Invalid key specification\n" + ex.toString());
        } catch (NoSuchAlgorithmException ex) {
            MSJ_JOptionPane.show_Error_Message("Error no such algorithm\n" + ex.toString());
        } catch (NoSuchPaddingException ex) {
            MSJ_JOptionPane.show_Error_Message("Error no such Padding\n" + ex.toString());
        } catch (InvalidKeyException ex) {
            MSJ_JOptionPane.show_Error_Message("Error in generating the secret key\n Or in valid key generated\n"
                    + ex.toString());
        } catch (IllegalBlockSizeException ex) {
            MSJ_JOptionPane.show_Error_Message("Error illegal block size\n" + ex.toString());
        } catch (BadPaddingException ex) {
            MSJ_JOptionPane.show_Error_Message("Error bad Padding\n" + ex.toString());
        } catch (IOException ex) {
            MSJ_JOptionPane.show_Error_Message("Input/Output Error\n" + ex.toString());
        }
        return output;
    }
}